//  泛型

// type NumberArr = number[]

//   1. 泛型的两种基础使用场景的写法
type NumberArr = Array<number>
type StringArr = Array<string>

// Promise对象
// typescript中 如果要声明一个Promise对象，类型上必须要说明 这个promise的结果的类型
type PromiseAny = Promise<any>

type PromiseNumber = Promise<number>

let p1: PromiseNumber = new Promise((resolve, reject) => {
    resolve(1)
})

let p7: PromiseNumber = Promise.resolve(99)

// 2. 泛型中的类型变量
//  思考题： 完成一个函数toPromise，函数接收一个参数，返回值就是参数的Promise形式
//  我们要能清晰的知道 返回的Promise结果的类型

// function toPromise(arg: number) {
//     return Promise.resolve(arg)
// }

// 此处的T 就是一个变量 它只能接收类型
function toPromise<T>(arg: T): Promise<T> {
    return Promise.resolve(arg)
}

// toPromise<number>(true)   报错了 

// 尖括号中的string 会作为类型传给 类型变量T   'A'会作为实参传递给形参 arg
toPromise<string>('A')

// 调用toPromise的时候， 可以把<>省掉，这就意味着 arg的类型 会作为 T的值
toPromise(1)

// 接口也支持泛型变量
interface IKeyValue<T, U> {
    key: T;
    value: U;
}

let o1: IKeyValue<number, string> = {
    key: 1,
    value: 'a'
}

// 接口可以用来描述函数
// interface IFunc {
//     <T>(): T
// }

// 类型的默认值
interface IFunc<T = number> {
    (arg: T): T
}

let fn: IFunc<string> = (arg) => arg

fn('a')